package store

import (
	"dingusxp/trial/guestbook/store"
	"dingusxp/trial/guestbook/store/factory"
	"sync"
)

func init() {

	factory.Register("mem", &MemStore{
		notes: make(map[uint64]*store.Note),
	})
}

type MemStore struct {
	sync.Mutex
	notes map[uint64]*store.Note
}

// interfaces
func (ms *MemStore) Create(note *store.Note) error {

	ms.Lock()
	defer ms.Unlock()

	_, dup := ms.notes[note.Id]
	if dup {
		return store.ErrorDuplicated
	}

	newNote := *note
	ms.notes[note.Id] = &newNote

	return nil
}

func (ms *MemStore) Get(id uint64) (store.Note, error) {

	ms.Lock()
	defer ms.Unlock()

	note, ok := ms.notes[id]
	if !ok {
		return store.Note{}, store.ErrorNotFound
	}
	return *note, nil
}

func (ms *MemStore) Update(note *store.Note) error {

	ms.Lock()
	defer ms.Unlock()

	_, ok := ms.notes[note.Id]
	if !ok {
		return store.ErrorNotFound
	}

	newNote := *note
	ms.notes[note.Id] = &newNote

	return nil
}

func (ms *MemStore) Delete(id uint64) error {

	ms.Lock()
	defer ms.Unlock()

	_, ok := ms.notes[id]
	if !ok {
		return store.ErrorNotFound
	}

	delete(ms.notes, id)
	return nil
}

func (ms *MemStore) ListAll() ([]store.Note, error) {

	ms.Lock()
	defer ms.Unlock()

	notes := make([]store.Note, 0, len(ms.notes))
	for _, note := range ms.notes {
		notes = append(notes, *note)
	}

	return notes, nil
}
